package at.ac.tuwien.isis.infret.ue2;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Vector;

import at.ac.tuwien.isis.infret.helper.ArffFilter;
import at.ac.tuwien.isis.infret.helper.DocumentContainer;

import jargs.gnu.CmdLineParser;

public class Retrieval 
{
	static String outputFolder = "output"+File.separatorChar;
	
	public Retrieval(Vector<String> indices, Vector<String> queryDocuments, Integer numberOfDocuments, String similarityFunction)
	{
		for (String query : queryDocuments){
			Vector<TreeMap<DocumentContainer,Double>> resultLists = new Vector<TreeMap<DocumentContainer,Double>>();
			Vector <String> wrapper = new Vector<String>();
			wrapper.add(query);
			
			for(String featureFile : indices){
				System.out.print("Working on index:"+featureFile);
				QueryHandler worker = new QueryHandler(featureFile);
				System.out.println("...Done");
				worker.SimilarityFunctionFlag = similarityFunction;
				System.out.print("Computing Similarity Function");
				resultLists.add(worker.applyQuery(wrapper, numberOfDocuments));
				System.out.println("...Done");
			}
			System.out.print("computing k-best Results (minimized across all indices):");
			
			HashMap<DocumentContainer, Double> finalResult = 
				Statistics.getkBest(resultLists,numberOfDocuments);

			System.out.println("...Done");
			System.out.print("writing Results:");
			
			try {
				File dir = new File(outputFolder);
				if(!dir.exists())dir.mkdir();
				HtmlOutput output = new HtmlOutput(dir.toString()+File.separatorChar+
					"output_"+query.split("/")[0]+"_"+query.split("/")[1]+".html");
				output.writeToHtml(finalResult,resultLists, wrapper, similarityFunction, indices,numberOfDocuments);
			} catch (IOException e) {
				System.err.println("Unable to open output File");
				e.printStackTrace();
			}
			System.out.println("...Done");
		}
	}
	
	public static void main(String []args)
	{
		/*
		 * CmdLineParser:
		 * 
		 * -i bzw --indices: (comma-separated) list of filenames
		 * -q bzw --queryDocuments: names of the query documents
		 * -k bzw --numberOfDocuments: number of to-be-retrieved documents
		 * -s bzw --similarityFunction: function for similarity retrieval (L2 or cosine)
		 */
      CmdLineParser parser = new CmdLineParser();
      CmdLineParser.Option indicesOpt = parser.addStringOption('i', "indices");
      CmdLineParser.Option queryDocumentsOpt = parser.addStringOption('q', "queryDocuments");
      CmdLineParser.Option numberOfDocumentsOpt = parser.addIntegerOption('k', "numberOfDocuments");
      CmdLineParser.Option similarityFunctionOpt = parser.addStringOption('s', "similarityFunction");
      
      // Parsen der CmdLine-Options
      try {
      	parser.parse(args);
      }
      catch ( CmdLineParser.OptionException e ) 
      {
      	System.err.println(e.getMessage());
	      printUsage();
	      System.exit(1);
      }
      
      String indicesStr = (String)parser.getOptionValue(indicesOpt, "");
      String queryDocumentsStr = (String)parser.getOptionValue(queryDocumentsOpt);
      Integer numberOfDocuments = (Integer)parser.getOptionValue(numberOfDocumentsOpt);
      String similarityFunction = (String)parser.getOptionValue(similarityFunctionOpt);
      if(numberOfDocuments == null  || numberOfDocuments.intValue() < 1 || queryDocumentsStr == null)
      {      	
      	printUsage();
      	System.exit(1);
      }
      if(!similarityFunction.toLowerCase().equals("l2") && !similarityFunction.toLowerCase().equals("cosine"))
      {
      	System.out.print("fehler: " + similarityFunction.toLowerCase());
      	printUsage();
      	System.exit(1);
      }
      if(indicesStr.equals("")){
    	  File currDir = new File(".");
    	  //System.out.println(currDir.toString());
    	  File[] arffList = currDir.listFiles(new ArffFilter());
    	  if (arffList.length == 0) {
    		  System.err.println("Error: No ARFF files in current directory, no alternative path given");
    		  printUsage();
    	      System.exit(1);
    	  }
    	  for(int i = 0 ; i < arffList.length; i++){
    		  indicesStr= indicesStr+ arffList[i].toString();
    		  if(i != arffList.length-1)indicesStr= indicesStr+",";
    	  }
      }
      Vector<String> indices = new Vector<String>(); 
      String[] indicesArray = indicesStr.split(",");
      for(int i = 0; i < indicesArray.length; i++)
      	indices.add(indicesArray[i].trim());
      
      Vector<String> queryDocuments = new Vector<String>(); 
      String[] queryDocumentsArray = queryDocumentsStr.split(",");
      for(int i = 0; i < queryDocumentsArray.length; i++)
      	queryDocuments.add(queryDocumentsArray[i].trim());
      
      System.out.println("indicesStr: " + indicesStr);
      System.out.println("queryDocumentsStr: " + queryDocumentsStr);
      System.out.println("numberOfDocuments: " + numberOfDocuments);
      System.out.println("similarityFunction:" + similarityFunction);
      /**
       * full report generation
       *
      for (int vector = 1; vector < (Math.pow(2, indices.size())); vector ++){
    	  int mask = 1; 
    	  Vector<String> indicesSubset= new Vector<String>();
    	  String folderName = "output"+File.separatorChar;
    	  for(int i = 0; i < indices.size();i++){
    		  //System.out.println(mask);
    		  if ((mask & vector) != 0 ){
    			  folderName+="("+indices.get(((int)(Math.log(mask)/Math.log(2)))).split("_")[1];
    			  folderName+=indices.get(((int)(Math.log(mask)/Math.log(2)))).split("_")[2]+")";                                                                     ;
    			  indicesSubset.add(indices.get((int)(Math.log(mask)/Math.log(2))) );
    		  }
    		  mask = mask<<1;
    	  }
    	  Retrieval.outputFolder = folderName+ File.separatorChar;
    	  
    	  new Retrieval(indicesSubset, queryDocuments, numberOfDocuments, similarityFunction);
          
    	  //System.out.println(".");
      }*/
      
      new Retrieval(indices, queryDocuments, numberOfDocuments, similarityFunction);
      System.exit(0);
	}
	
	private static void printUsage() 
	{
		System.err.println(
				"Wrong or missing options. Available options:"
		);
		System.err.println(
				"Option                                         Description\n" + 
				"------                                         -----------\n" +
				"-i, --indices [Path]+                          (comma-separated) list of filenames, leave blank for usage of .arff files in current directory\n" +
				"-q, --queryDocuments [Path]+                   names of the query documents (mandatory) (please don't use blanks!!)\n"+
				"-k, --numberOfDocuments [Integer: value]       number of to-be-retrieved documents\n" +
				"-s, --similarityFunction [String]              function for similarity retrieval (L2 or cosine)\n"				
		);
  }
}
